package com.shioirikukuri.controller;

import com.shioirikukuri.common.result.Result;
import com.shioirikukuri.entity.DiningTable;
import com.shioirikukuri.entity.ReservationOrder;
import com.shioirikukuri.service.IDiningTableService;
import com.shioirikukuri.service.IReservationDiningStatusService;
import com.shioirikukuri.service.IReservationOrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
@RequestMapping("/api/reservation-orders")
public class ReservationOrderController {

	@Autowired
	private IReservationOrderService reservationOrderService;

	@Autowired
	private IDiningTableService diningTableService;

	@Autowired
	private IReservationDiningStatusService reservationDiningStatusService;

	@Autowired
	private RedisTemplate<String, String> redisTemplate;

	/**
	 * 创建普通预约
	 * @param reservationOrder
	 * @return reservationOrderId
	 */
	@PostMapping("/createNormalReservation")
	public Result<Integer> createNormalReservation(@RequestBody ReservationOrder reservationOrder) {
		// 1. 校验预约类型是否为普通预约
		if (!ReservationOrder.TYPE_NORMAL.equals(reservationOrder.getReservationType())) {
			return Result.error(400, "预约类型必须是普通预约");
		}

		// 2. 获取所有普通预约桌位
		List<DiningTable> normalTables = diningTableService.getDiningTableByType(DiningTable.TYPE_NORMAL);
		if (normalTables == null || normalTables.isEmpty()) {
			return Result.error(400, "没有可用的普通预约桌位");
		}

		// 3. 初始化 Redis 数据（如果 Redis 中没有数据）
		initializeRedisDataIfNeeded(normalTables);

		// 4. 寻找最匹配的桌位
		DiningTable bestMatchTable = findBestMatchTable(normalTables, reservationOrder.getSeatCount());
		if (bestMatchTable == null) {
			return Result.error(400, "没有合适的桌位");
		}

		// 5. 检查 Redis 中该桌位的剩余可用数量
		String key = bestMatchTable.getTableName();
		String value = redisTemplate.opsForValue().get(key);
		Integer availableCount = value == null ? null : Integer.parseInt(value);
		if (availableCount == null || availableCount <= 0) {
			return Result.error(400, "该桌位已满");
		}

		// 6. 创建预约订单
		reservationOrderService.createReservationOrder(reservationOrder);

		// 7. 更新 Redis 中该桌位的剩余可用数量
		redisTemplate.opsForValue().set(key, String.valueOf(availableCount - 1));



		// 创建预约订单并获取其ID
		Integer reservationOrderId = reservationOrderService.createReservationOrder(reservationOrder);

		// 返回结果
		return Result.success(reservationOrderId);
	}





	/**
	 * 初始化 Redis 数据（如果 Redis 中没有数据）
	 *
	 * @param tables 桌位列表
	 */
	private void initializeRedisDataIfNeeded(List<DiningTable> tables) {
		for (DiningTable table : tables) {
			String key = table.getTableName();
			String redisValue = redisTemplate.opsForValue().get(key); // 获取 String 类型
			if (redisValue == null) {
				// 如果 Redis 中没有数据，从数据库加载并存储到 Redis
				Integer dbValue = table.getAvailableCount();
				redisTemplate.opsForValue().set(key, dbValue.toString()); // 转为 String 再存入
			}
		}
	}


	/**
	 * 寻找最匹配的桌位
	 *
	 * @param tables      桌位列表
	 * @param seatCount   需要的座位数
	 * @return 最匹配的桌位
	 */
	private DiningTable findBestMatchTable(List<DiningTable> tables, Integer seatCount) {
		// 优先匹配座位数相等的桌位
		for (DiningTable table : tables) {
			if (table.getCapacity().equals(seatCount)) {
				return table;
			}
		}

		// 如果没有完全匹配的桌位，则向上寻找
		for (DiningTable table : tables) {
			if (table.getCapacity() >= seatCount) {
				return table;
			}
		}

		return null; // 没有找到合适的桌位
	}
	@GetMapping
	public List<ReservationOrder> getAllReservationOrders() {
		return reservationOrderService.getAllReservationOrders();
	}

	@GetMapping("/{orderId}")
	public ReservationOrder getReservationOrderById(@PathVariable Integer orderId) {
		return reservationOrderService.getReservationOrderById(orderId);
	}

	@GetMapping("/type/{reservationType}")
	public List<ReservationOrder> getReservationOrdersByType(@PathVariable String reservationType) {
		return reservationOrderService.getReservationOrdersByType(reservationType);
	}

	@PostMapping
	public void createReservationOrder(@RequestBody ReservationOrder reservationOrder) {
		reservationOrderService.createReservationOrder(reservationOrder);
	}

	@PutMapping("/{orderId}")
	public void updateReservationOrder(@PathVariable Integer orderId, @RequestBody ReservationOrder reservationOrder) {
		reservationOrderService.updateReservationOrder(reservationOrder);
	}

	@DeleteMapping("/{orderId}")
	public void deleteReservationOrderById(@PathVariable Integer orderId) {
		reservationOrderService.deleteReservationOrderById(orderId);
	}
}